Latest Date of Dataset: 2020-04-01
Updated: 2020-04-02 16:06:33 EST
This dashboard is used to track the current progress of the COVID-19 progress throughout the world. The visualization and information presented are automatically updated daily with current data scraped from the Johns Hopkin’s COVID-19 Data Repository. Their data is retrieved for sources such as World Health Organization (WHO), China CDC, US CDC, and more.
The data is cleaned and aggregated through R, formatted in Rmarkdown, and exported as an HTML document to be hosted through GitPages. The source R notebook can be found at covid19-daily-dashboard.Rmd in the GitHub repository.
Overview of Cases (2020-04-01)
Below is an interactive plot displaying the number of confirmed, dead, and recovered cases per country and province if data is specified. The data was aggregated from the Johns Hopkins’s data repository and this notebook is set to run nightly to provide up to date results
Confirmed Cases per Country
The table below shows aggregated data of each country’s confirmed, recovered, and dead population. Each column can be sorted to view least or most of each status. The graphs below show the total and daily count of confirmed cases for the countries with the most cases and are tracked by days since the first reported case.
(*China’s dataset goes back further and therefore does not align with other countries)
COVID19 Cases Spread Timelapse
The time-lapse was produced through gganimate and shows the spread of the virus since 22Jan2020. The time-lapse cycles through the dates, showing the color coded increase of confirmed, recovered, and death cases across the world.

New Cases of the Day (2020-04-01)
The ‘New Cases of the Day’ map displays all confirmed cases of the specified date. The map was produced through Leaflet and provides a detailed and interactive map that shows the location and number of cases of the day.
Also, to differentiate if the case of the day is the first case in the specified location, it is highlighted red. All the specified points on the map are listed in the table below, including cumulative count of each location.
New Cases of the Week (2020-04-01)
The ‘New Cases of the Week’ map displays all confirmed cases of the week starting from the specified date. This map shows the same information as the daily cases map but includes all cases in the past week.
General Trends
The plots below outlines general trends seen of the virus over time:
“Percent of Cases Recovered or Dead per Day”: the total percent of cases that have resulted in recovery or death per confirmed case
“Cumulative Status of All Cases”: the continuous increase of confirmed, death, and recovered cases over time
“Status of Cases per Day”: the number of cases classified as confirmed, death, or recovered subtracted to show per day changes



LS0tDQp0aXRsZTogIkNPVklEMTkgRGFpbHkgRGFzaGJvYXJkIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQogICAgDQotLS0NCg0KYGBge3IgU2V0dXAsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQojIEludGVyYWN0aW9uDQpsaWJyYXJ5KHJ2ZXN0KQ0KbGlicmFyeShyc3R1ZGlvYXBpKQ0KbGlicmFyeShkcmF0KQ0KbGlicmFyeShnaXQycikNCg0KIyBBZ2dyZWdhdGlvbg0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkodGlkeXIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShEVCkNCg0KIyBWaXN1YWxpemF0aW9ucw0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShsZWFmbGV0KQ0KbGlicmFyeShnZ3RoZW1lcykNCmxpYnJhcnkoZ2dhbmltYXRlKQ0KbGlicmFyeShtYXBzKQ0KbGlicmFyeShwbmcpDQpsaWJyYXJ5KGdpZnNraSkNCmxpYnJhcnkocGxvdGx5KQ0KYGBgDQoNCg0KYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQ0KbGluayA8LSAiaHR0cHM6Ly9naXRodWIuY29tLy9DU1NFR0lTYW5kRGF0YS9DT1ZJRC0xOS9yYXcvbWFzdGVyL2Nzc2VfY292aWRfMTlfZGF0YS9jc3NlX2NvdmlkXzE5X3RpbWVfc2VyaWVzLyINCmNzdl9saXN0IDwtIGMoDQogICJ0aW1lX3Nlcmllc19jb3ZpZDE5X2NvbmZpcm1lZF9nbG9iYWwuY3N2IiwNCiAgInRpbWVfc2VyaWVzX2NvdmlkMTlfZGVhdGhzX2dsb2JhbC5jc3YiLA0KICAidGltZV9zZXJpZXNfY292aWQxOV9yZWNvdmVyZWRfZ2xvYmFsLmNzdiINCikNCg0KDQpmb3IgKGNzdiBpbiBjc3ZfbGlzdCkgew0KICBwYXRoIDwtIHBhc3RlKGxpbmssIGNzdiwgc2VwID0gIiIpDQogIGRvd25sb2FkX3BhdGggPC0gcGFzdGUoImRhdGFfcmF3LyIsIGNzdiwgc2VwID0gIiIpDQogIGRvd25sb2FkLmZpbGUocGF0aCwgZGVzdGZpbGUgPSBkb3dubG9hZF9wYXRoKQ0KfQ0KYGBgDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KY3ZfY29uIDwtIHJlYWRfY3N2KCJkYXRhX3Jhdy90aW1lX3Nlcmllc19jb3ZpZDE5X2NvbmZpcm1lZF9nbG9iYWwuY3N2IikgJT4lDQogIGdhdGhlcihrZXkgPSAiRGF0ZSIsIHZhbHVlID0gQ29uZmlybWVkLCAtTGF0LCAtTG9uZywgLWBQcm92aW5jZS9TdGF0ZWAsIC1gQ291bnRyeS9SZWdpb25gKQ0KDQpjdl9kZWQgPC0gcmVhZF9jc3YoImRhdGFfcmF3L3RpbWVfc2VyaWVzX2NvdmlkMTlfZGVhdGhzX2dsb2JhbC5jc3YiKSAlPiUNCiAgZ2F0aGVyKGtleSA9ICJEYXRlIiwgdmFsdWUgPSBEZWFkLCAtTGF0LCAtTG9uZywgLWBQcm92aW5jZS9TdGF0ZWAsIC1gQ291bnRyeS9SZWdpb25gKQ0KDQpjdl9yZWMgPC0gcmVhZF9jc3YoImRhdGFfcmF3L3RpbWVfc2VyaWVzX2NvdmlkMTlfcmVjb3ZlcmVkX2dsb2JhbC5jc3YiKSAlPiUNCiAgZ2F0aGVyKGtleSA9ICJEYXRlIiwgdmFsdWUgPSBSZWNvdmVyZWQsIC1MYXQsIC1Mb25nLCAtYFByb3ZpbmNlL1N0YXRlYCwgLWBDb3VudHJ5L1JlZ2lvbmApDQpgYGANCg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmN2X21lcmdlIDwtIG1lcmdlKGN2X2NvbiwgY3ZfZGVkLCBieSA9IGMoIlByb3ZpbmNlL1N0YXRlIiwgIkxhdCIsICJMb25nIiwgIkNvdW50cnkvUmVnaW9uIiwgIkRhdGUiKSwgYWxsID0gVFJVRSkgJT4lDQogIG1lcmdlKGN2X3JlYywgYnkgPSBjKCJQcm92aW5jZS9TdGF0ZSIsICJMYXQiLCAiTG9uZyIsICJDb3VudHJ5L1JlZ2lvbiIsICJEYXRlIiksIGFsbCA9IFRSVUUpICU+JQ0KICByZW5hbWUoIkNvdW50cnlfUmVnaW9uIiA9ICJDb3VudHJ5L1JlZ2lvbiIpICU+JQ0KICByZW5hbWUoIlByb3ZpbmNlX1N0YXRlIiA9ICJQcm92aW5jZS9TdGF0ZSIpDQpjdl9tZXJnZSREYXRlIDwtIGFzLkRhdGUoY3ZfbWVyZ2UkRGF0ZSwgZm9ybWF0ID0gIiVtLyVkLyV5IikNCg0KY3YgPC0gZ2F0aGVyKGN2X21lcmdlLCBrZXkgPSAiU3RhdHVzIiwgdmFsdWUgPSBDb3VudCwgLURhdGUsIC1MYXQsIC1Mb25nLCAtUHJvdmluY2VfU3RhdGUsIC1Db3VudHJ5X1JlZ2lvbikNCmN2IDwtIGN2W3dpdGgoY3YsIG9yZGVyKENvdW50cnlfUmVnaW9uLCBQcm92aW5jZV9TdGF0ZSwgU3RhdHVzLCBEYXRlKSksIF0NCmBgYA0KDQoNCg0KYGBge3IgZnVuY3Rpb25fY2hlY2tfZmlyc3RfY2FzZSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmNoZWNrX2NvbnRpbnVvdXMgPC0gZnVuY3Rpb24oeCwgY3YsIG51bV9wcmV2KSB7DQogIGlmICgNCiAgICAoY3YkTG9uZ1t4XSAhPSBjdiRMb25nW3ggLSBudW1fcHJldl0pIHx8DQogICAgICAoY3YkTGF0W3hdICE9IGN2JExhdFt4IC0gbnVtX3ByZXZdKSB8fA0KICAgICAgKGN2JFN0YXR1c1t4XSAhPSBjdiRTdGF0dXNbeCAtIG51bV9wcmV2XSkpIHsNCiAgICBjb250IDwtICJOIg0KICB9DQogIGVsc2Ugew0KICAgIGNvbnQgPC0gIlkiDQogIH0NCiAgcmV0dXJuKGNvbnQpDQp9DQoNCg0KZGFpbHlfd2Vla2x5X2NvdW50ZXIgPC0gZnVuY3Rpb24oY3YpIHsNCiAgZm9yICh4IGluIHNlcSgxLCBucm93KGN2KSkpIHsNCiAgICBpZiAoeCA9PSAxKSB7DQogICAgICBjdiREYWlseV9Db3VudFt4XSA8LSBOQQ0KICAgICAgY3YkV2Vla2x5X0NvdW50W3hdIDwtIE5BDQogICAgfQ0KICAgIGVsc2UgaWYgKGNoZWNrX2NvbnRpbnVvdXMoeCwgY3YsIDEpID09ICJOIikgew0KICAgICAgY3YkRGFpbHlfQ291bnRbeF0gPC0gTkENCiAgICAgIGN2JFdlZWtseV9Db3VudFt4XSA8LSBOQQ0KICAgIH0NCiAgICBlbHNlIGlmICh4IDw9IDcpIHsNCiAgICAgIGN2JERhaWx5X0NvdW50W3hdIDwtIChjdiRDb3VudFt4XSkgLSAoY3YkQ291bnRbeCAtIDFdKQ0KICAgICAgY3YkV2Vla2x5X0NvdW50W3hdIDwtIE5BDQogICAgfQ0KICAgIGVsc2UgaWYgKChjaGVja19jb250aW51b3VzKHgsIGN2LCAxKSA9PSAiWSIpICYmDQogICAgICAoY2hlY2tfY29udGludW91cyh4LCBjdiwgNykgPT0gIk4iKSkgew0KICAgICAgY3YkRGFpbHlfQ291bnRbeF0gPC0gKGN2JENvdW50W3hdKSAtIChjdiRDb3VudFt4IC0gMV0pDQogICAgICBjdiRXZWVrbHlfQ291bnRbeF0gPC0gTkENCiAgICB9DQogICAgZWxzZSBpZiAoKGNoZWNrX2NvbnRpbnVvdXMoeCwgY3YsIDcpID09ICJZIikpIHsNCiAgICAgIGN2JERhaWx5X0NvdW50W3hdIDwtIChjdiRDb3VudFt4XSkgLSAoY3YkQ291bnRbeCAtIDFdKQ0KICAgICAgY3YkV2Vla2x5X0NvdW50W3hdIDwtIChjdiRDb3VudFt4XSkgLSAoY3YkQ291bnRbeCAtIDddKQ0KICAgIH0NCiAgfQ0KICByZXR1cm4oY3YpDQp9DQpgYGANCg0KDQpgYGB7ciwgYXBwbHlfY2hlY2tfY2FzZSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmN2IDwtIGRhaWx5X3dlZWtseV9jb3VudGVyKGN2KQ0KbGF0ZXN0X2RhdGUgPC0gYXMuRGF0ZShTeXMuRGF0ZSgpKSAtIDENCiNsYXRlc3RfZGF0ZSA8LSBzb3J0KGN2JERhdGUsIGRlY3JlYXNpbmcgPSBUUlVFKVsxXSAtIDENCmN2IDwtIGZpbHRlcihjdiwgRGF0ZSA8PSBsYXRlc3RfZGF0ZSkNCmBgYA0KDQojIyMjIyBMYXRlc3QgRGF0ZSBvZiBEYXRhc2V0OiBgciBsYXRlc3RfZGF0ZWANCiMjIyMjIyBVcGRhdGVkOiBgciBTeXMudGltZSgpYCBFU1QNCg0KVGhpcyBkYXNoYm9hcmQgaXMgdXNlZCB0byB0cmFjayB0aGUgY3VycmVudCBwcm9ncmVzcyBvZiB0aGUgQ09WSUQtMTkgcHJvZ3Jlc3MgdGhyb3VnaG91dCB0aGUgd29ybGQuIFRoZSB2aXN1YWxpemF0aW9uIGFuZCBpbmZvcm1hdGlvbiBwcmVzZW50ZWQgYXJlIGF1dG9tYXRpY2FsbHkgdXBkYXRlZCBkYWlseSB3aXRoIGN1cnJlbnQgZGF0YSBzY3JhcGVkIGZyb20gdGhlIFtKb2hucyBIb3BraW7igJlzIENPVklELTE5IERhdGEgUmVwb3NpdG9yeV0oaHR0cHM6Ly9naXRodWIuY29tL0NTU0VHSVNhbmREYXRhL0NPVklELTE5KS4gVGhlaXIgZGF0YSBpcyByZXRyaWV2ZWQgZm9yIHNvdXJjZXMgc3VjaCBhcyBXb3JsZCBIZWFsdGggT3JnYW5pemF0aW9uIChXSE8pLCBDaGluYSBDREMsIFVTIENEQywgYW5kIG1vcmUuDQoNClRoZSBkYXRhIGlzIGNsZWFuZWQgYW5kIGFnZ3JlZ2F0ZWQgdGhyb3VnaCBSLCBmb3JtYXR0ZWQgaW4gUm1hcmtkb3duLCBhbmQgZXhwb3J0ZWQgYXMgYW4gSFRNTCBkb2N1bWVudCB0byBiZSBob3N0ZWQgdGhyb3VnaCBHaXRQYWdlcy4gVGhlIHNvdXJjZSBSIG5vdGVib29rIGNhbiBiZSBmb3VuZCBhdCBbY292aWQxOS1kYWlseS1kYXNoYm9hcmQuUm1kXShodHRwczovL2dpdGh1Yi5jb20vYWxiZWNoZW4vY292aWQxOS1kYWlseS1kYXNoYm9hcmQvYmxvYi9tYXN0ZXIvY292aWQxOS1kYWlseS1kYXNoYm9hcmQuUm1kKSBpbiB0aGUgW0dpdEh1YiByZXBvc2l0b3J5XShodHRwczovL2dpdGh1Yi5jb20vYWxiZWNoZW4vY292aWQxOS1kYWlseS1kYXNoYm9hcmQpLg0KDQoNCmBgYHtyIGVtcHR5X2RmX2Z1bmN0aW9uLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZW1wdHlfZGYgPC0gZnVuY3Rpb24oKSB7DQogIGVtcHR5X2RmIDwtIGRhdGEuZnJhbWUoDQogICAgUHJvdmluY2VfU3RhdGUgPSBjaGFyYWN0ZXIoMCksDQogICAgTGF0ID0gZG91YmxlKCksIExvbmcgPSBkb3VibGUoKSwNCiAgICBDb3VudHJ5X1JlZ2lvbiA9IGNoYXJhY3RlcigwKSwNCiAgICBEYXRlID0gYXMuRGF0ZShjaGFyYWN0ZXIoKSksDQogICAgU3RhdHVzID0gY2hhcmFjdGVyKDApLA0KICAgIENvdW50ID0gZG91YmxlKCksDQogICAgRGFpbHlfQ291bnQgPSBkb3VibGUoKSwgV2Vla2x5X0NvdW50ID0gZG91YmxlKCkNCiAgKQ0KICBlbXB0eV9kZiRQcm92aW5jZV9TdGF0ZSA8LSBhcy5jaGFyYWN0ZXIoZW1wdHlfZGYkUHJvdmluY2VfU3RhdGUpDQogIGVtcHR5X2RmJENvdW50cnlfUmVnaW9uIDwtIGFzLmNoYXJhY3RlcihlbXB0eV9kZiRDb3VudHJ5X1JlZ2lvbikNCiAgZW1wdHlfZGYkU3RhdHVzIDwtIGFzLmNoYXJhY3RlcihlbXB0eV9kZiRTdGF0dXMpDQogIHJldHVybihlbXB0eV9kZikNCn0NCmBgYA0KDQoNCmBgYHtyIG5ld19jYXNlc19hZ2csIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpmaXJzdF9hbmRfbmV3X2Nhc2VzIDwtIGZ1bmN0aW9uKGN2LCBkYXlzKSB7DQogIGhpZ2hfZGF0ZSA8LSBzb3J0KGN2JERhdGUsIGRlY3JlYXNpbmcgPSBUUlVFKVsxXSAtIDENCiAgY3YgPC0gY3YgJT4lIA0KICAgIGZpbHRlcihTdGF0dXMgPT0gIkNvbmZpcm1lZCIsICFpcy5uYShDb3VudCkpDQogIGN2JEZpcnN0X0Nhc2UgPC0gRkFMU0UNCg0KICBmb3IgKHggaW4gc2VxKDEsIG5yb3coY3YpKSkgew0KICAgIGlmICgNCiAgICAgIChjdiREYXRlW3hdID09IGhpZ2hfZGF0ZSkgJiYNCiAgICAgICAgKGN2JENvdW50W3ggLSBkYXlzXSA9PSAwKSAmJg0KICAgICAgICAoY3YkQ291bnRbeF0gPiAwKQ0KICAgICkgew0KICAgICAgY3YkRmlyc3RfQ2FzZVt4XSA8LSBUUlVFDQogICAgfQ0KICB9DQoNCiAgbmV3X2Nhc2VzX2RmIDwtIGZpbHRlcihjdiwgRGF0ZSA9PSBoaWdoX2RhdGUpDQoNCiAgaWYgKGRheXMgPT0gMSkgew0KICAgIG5ld19jYXNlc19kZiA8LSBmaWx0ZXIobmV3X2Nhc2VzX2RmLCBEYWlseV9Db3VudCA+IDApDQogIH0NCiAgZWxzZSBpZiAoZGF5cyA9PSA3KSB7DQogICAgbmV3X2Nhc2VzX2RmIDwtIGZpbHRlcihuZXdfY2FzZXNfZGYsIFdlZWtseV9Db3VudCA+IDApDQogIH0NCg0KICByZXR1cm4obmV3X2Nhc2VzX2RmKQ0KfQ0KDQpuZXdfY2FzZXNfZGF5IDwtIGZpcnN0X2FuZF9uZXdfY2FzZXMoY3YsIDEpDQpuZXdfY2FzZXNfd2VlayA8LSBmaXJzdF9hbmRfbmV3X2Nhc2VzKGN2LCA3KQ0KYGBgDQoNCg0KYGBge3IsIGVjaG89RkFMU0V9DQpjdl9sYXRlc3QgPC0gZmlsdGVyKGN2X21lcmdlLCBEYXRlID09IGxhdGVzdF9kYXRlKQ0KY3ZfbGF0ZXN0IDwtIGN2X2xhdGVzdFt3aXRoKGN2X2xhdGVzdCwgb3JkZXIoLUNvbmZpcm1lZCwgLVJlY292ZXJlZCwgLURlYWQpKSwgXQ0KYGBgDQoNCiMjIyBPdmVydmlldyBvZiBDYXNlcyAoYHIgbGF0ZXN0X2RhdGVgKQ0KQmVsb3cgaXMgYW4gaW50ZXJhY3RpdmUgcGxvdCBkaXNwbGF5aW5nIHRoZSBudW1iZXIgb2YgY29uZmlybWVkLCBkZWFkLCBhbmQgcmVjb3ZlcmVkIGNhc2VzIHBlciBjb3VudHJ5IGFuZCBwcm92aW5jZSBpZiBkYXRhIGlzIHNwZWNpZmllZC4gVGhlIGRhdGEgd2FzIGFnZ3JlZ2F0ZWQgZnJvbSB0aGUgSm9obnMgSG9wa2lucydzIGRhdGEgcmVwb3NpdG9yeSBhbmQgdGhpcyBub3RlYm9vayBpcyBzZXQgdG8gcnVuIG5pZ2h0bHkgdG8gcHJvdmlkZSB1cCB0byBkYXRlIHJlc3VsdHMNCmBgYHtyIGZ1bGxfcGxvdCwgZWNobz1GQUxTRX0NCmN2X2xhdGVzdF9sYWJlbHMgPC0gZnVuY3Rpb24oZGYpIHsNCiAgbGFicyA8LSBsYXBwbHkoc2VxKG5yb3coZGYpKSwgZnVuY3Rpb24oaSkgew0KICAgIHBhc3RlMCgNCiAgICAgICJDb3VudHJ5OiAiLCBkZltpLCAiQ291bnRyeV9SZWdpb24iXSwgIjxicj4gIiwNCiAgICAgICJQcm92aW5jZTogIiwgZGZbaSwgIlByb3ZpbmNlX1N0YXRlIl0sICI8YnI+IiwNCiAgICAgICJDb25maXJtZWQ6ICIsIGRmW2ksICJDb25maXJtZWQiXSwgIjxicj4iLA0KICAgICAgIkRlYWQ6ICIsIGRmW2ksICJEZWFkIl0sICI8YnI+IiwNCiAgICAgICJSZWNvdmVyZWQ6ICIsIGRmW2ksICJSZWNvdmVyZWQiXSwgIjxicj4iLA0KICAgICAgIkRhdGU6ICIsIGRmW2ksICJEYXRlIl0NCiAgICApDQogIH0pDQp9DQoNCmxlYWZsZXQoZGF0YSA9IGN2X2xhdGVzdCwgd2lkdGggPSAiMTAwJSIpICU+JQ0KICBhZGRUaWxlcygpICU+JQ0KICBhZGRDaXJjbGVNYXJrZXJzKA0KICAgIGxhdCA9IH5MYXQsDQogICAgbG5nID0gfkxvbmcsDQogICAgcmFkaXVzID0gfiBsb2coQ29uZmlybWVkLCAxLjEpLzEwLA0KICAgIGxhYmVsID0gbGFwcGx5KGN2X2xhdGVzdF9sYWJlbHMoY3ZfbGF0ZXN0KSwgaHRtbHRvb2xzOjpIVE1MKQ0KICApDQpgYGANCg0KDQojIyMgQ29uZmlybWVkIENhc2VzIHBlciBDb3VudHJ5DQpUaGUgdGFibGUgYmVsb3cgc2hvd3MgYWdncmVnYXRlZCBkYXRhIG9mIGVhY2ggY291bnRyeSdzIGNvbmZpcm1lZCwgcmVjb3ZlcmVkLCBhbmQgZGVhZCBwb3B1bGF0aW9uLiBFYWNoIGNvbHVtbiBjYW4gYmUgc29ydGVkIHRvIHZpZXcgbGVhc3Qgb3IgbW9zdCBvZiBlYWNoIHN0YXR1cy4gVGhlIGdyYXBocyBiZWxvdyBzaG93IHRoZSB0b3RhbCBhbmQgZGFpbHkgY291bnQgb2YgY29uZmlybWVkIGNhc2VzIGZvciB0aGUgY291bnRyaWVzIHdpdGggdGhlIG1vc3QgY2FzZXMgYW5kIGFyZSB0cmFja2VkIGJ5IGRheXMgc2luY2UgdGhlIGZpcnN0IHJlcG9ydGVkIGNhc2UuDQoNCigqQ2hpbmEncyBkYXRhc2V0IGdvZXMgYmFjayBmdXJ0aGVyIGFuZCB0aGVyZWZvcmUgZG9lcyBub3QgYWxpZ24gd2l0aCBvdGhlciBjb3VudHJpZXMpDQoNCg0KYGBge3IgY291bnRyeV90YWJsZSwgZWNobz1GQUxTRX0NCmNvdW50cnlfdGFibGUgPC0gY3ZfbWVyZ2UgJT4lDQogIHNlbGVjdChDb3VudHJ5X1JlZ2lvbiwgQ29uZmlybWVkLCBSZWNvdmVyZWQsIERlYWQsIERhdGUpICU+JQ0KICBncm91cF9ieShDb3VudHJ5X1JlZ2lvbikgJT4lDQogIGZpbHRlcihEYXRlPT1sYXRlc3RfZGF0ZSkgJT4lDQogIHNlbGVjdChDb3VudHJ5X1JlZ2lvbiwgQ29uZmlybWVkLCBSZWNvdmVyZWQsIERlYWQpICU+JQ0KICBzdW1tYXJpc2VfYWxsKHN1bSkNCmNvdW50cnlfdGFibGUgPC0gY291bnRyeV90YWJsZVt3aXRoKGNvdW50cnlfdGFibGUsIG9yZGVyKC1Db25maXJtZWQsIC1SZWNvdmVyZWQsIC1EZWFkKSksIF0NCg0KY291bnRyeV90YWJsZQ0KYGBgDQoNCmBgYHtyIGRmX2Zvcl90b3BfY291bnRyaWVzLCBlY2hvPUZBTFNFfQ0KdG9wXzEwX2NvdW50cmllcyA8LSAoaGVhZChjb3VudHJ5X3RhYmxlJENvdW50cnlfUmVnaW9uLCAxNikpDQoNCnRvcDEwX2RmIDwtIGN2ICU+JQ0KICBmaWx0ZXIoKGN2JENvdW50cnlfUmVnaW9uICVpbiUgYyh0b3BfMTBfY291bnRyaWVzKSkgJiAoY3YkU3RhdHVzID09ICdDb25maXJtZWQnKSwgKGN2JENvdW50cnlfUmVnaW9uICE9ICdDaGluYScpKSAlPiUNCiAgc2VsZWN0KENvdW50cnlfUmVnaW9uLCBEYXRlLCBDb3VudCwgRGFpbHlfQ291bnQpICU+JQ0KICBncm91cF9ieShDb3VudHJ5X1JlZ2lvbiwgRGF0ZSkgJT4lDQogIHN1bW1hcmlzZShDb3VudCA9IHN1bShDb3VudCwgbmEucm0gPSBUUlVFKSwgRGFpbHlfQ291bnQgPSBzdW0oRGFpbHlfQ291bnQsIG5hLnJtID0gVFJVRSkpDQoNCg0KdG9wMTBfZGYgPC0gdG9wMTBfZGZbd2l0aCh0b3AxMF9kZiwgb3JkZXIoQ291bnRyeV9SZWdpb24sIERhdGUpKSwgXQ0KdG9wMTBfZGYkYERheXMgU2luY2UgRmlyc3QgQ2FzZWAgPC0gMA0KDQpmb3IgKHggaW4gc2VxKDIsIG5yb3codG9wMTBfZGYpKSkgew0KICBpZiAoKHRvcDEwX2RmJENvdW50cnlfUmVnaW9uW3hdID09IHRvcDEwX2RmJENvdW50cnlfUmVnaW9uW3gtMV0pICYgKHRvcDEwX2RmJENvdW50W3hdID49IDI1KSkgew0KICAgIGlmICh0b3AxMF9kZiRgRGF5cyBTaW5jZSBGaXJzdCBDYXNlYFt4LTFdID09IDApew0KICAgICAgaWYgKHRvcDEwX2RmJERhaWx5X0NvdW50W3hdID4gMCkgew0KICAgICAgICB0b3AxMF9kZiRgRGF5cyBTaW5jZSBGaXJzdCBDYXNlYFt4XSA8LSAxDQogICAgICB9DQogICAgfQ0KICAgIGVsc2Ugew0KICAgICAgaW50ZXJ2YWwgPC0gdG9wMTBfZGYkYERheXMgU2luY2UgRmlyc3QgQ2FzZWBbeC0xXQ0KICAgICAgdG9wMTBfZGYkYERheXMgU2luY2UgRmlyc3QgQ2FzZWBbeF0gPC0gMSArIGludGVydmFsDQogICAgfQ0KICB9DQp9DQpgYGANCg0KDQpgYGB7ciBwbG90bHlfdG90YWxfY2FzZXMsIGVjaG89RkFMU0UsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD02fQ0KdG9wMTBfZGZfd2lkZV9jb3VudCA8LSB0b3AxMF9kZiAlPiUNCiAgZmlsdGVyKGBEYXlzIFNpbmNlIEZpcnN0IENhc2VgICE9IDApICU+JQ0KICBzZWxlY3QoQ291bnRyeV9SZWdpb24sIENvdW50LCBgRGF5cyBTaW5jZSBGaXJzdCBDYXNlYCkgJT4lDQogIHNwcmVhZChrZXk9Q291bnRyeV9SZWdpb24sIHZhbHVlPUNvdW50KQ0KDQoNCmZpZyA8LSB0b3AxMF9kZl93aWRlX2NvdW50ICU+JSBwbG90X2x5KCkNCg0KZm9yIChrIGluIDI6bGVuZ3RoKHRvcF8xMF9jb3VudHJpZXMpKSB7DQogIGNvdW50cnlfZGYgPC0gZGF0YS5mcmFtZSh5PXRvcDEwX2RmX3dpZGVfY291bnRbW2tdXSwgeD10b3AxMF9kZl93aWRlX2NvdW50W1sxXV0pDQogIGZpZyA8LSBhZGRfdHJhY2UoZmlnLCB5PX55LCB4PX54LCBkYXRhPWNvdW50cnlfZGYsIHR5cGU9InNjYXR0ZXIiLCBtb2RlPSJsaW5lcyIsIG5hbWUgPSBjb2xuYW1lcyh0b3AxMF9kZl93aWRlX2NvdW50KVtrXSkNCn0NCg0KZmlnIDwtIGZpZyAlPiUgbGF5b3V0KA0KICAgIHRpdGxlID0gIlRvdGFsIENvbmZpcm1lZCBDYXNlcyBTaW5jZSBGaXJzdCAyNSBDYXNlcyIsDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlPSdEYXlzIFNpbmNlIEZpcnN0IDI1IENhc2VzJywgcmFuZ2VzbGlkZXIgPSBsaXN0KHR5cGUgPSAiaW50IikpLA0KICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJUb3RhbCBDb3VudCIpKQ0KDQoNCmZpZw0KYGBgDQoNCmBgYHtyIHBsb3RfZmlyc3RfY2FzZXNfdG90YWwsIGVjaG89RkFMU0UsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD02fSAgDQp0b3AxMF9kZl93aWRlX2RhaWx5IDwtIHRvcDEwX2RmICU+JQ0KICBmaWx0ZXIoYERheXMgU2luY2UgRmlyc3QgQ2FzZWAgIT0gMCkgJT4lDQogIHNlbGVjdChDb3VudHJ5X1JlZ2lvbiwgRGFpbHlfQ291bnQsIGBEYXlzIFNpbmNlIEZpcnN0IENhc2VgKSAlPiUNCiAgc3ByZWFkKGtleT1Db3VudHJ5X1JlZ2lvbiwgdmFsdWU9RGFpbHlfQ291bnQpDQoNCg0KZmlnIDwtIHRvcDEwX2RmX3dpZGVfZGFpbHkgJT4lIHBsb3RfbHkoKQ0KDQpmb3IgKGsgaW4gMjpsZW5ndGgodG9wXzEwX2NvdW50cmllcykpIHsNCiAgY291bnRyeV9kZiA8LSBkYXRhLmZyYW1lKHk9dG9wMTBfZGZfd2lkZV9kYWlseVtba11dLCB4PXRvcDEwX2RmX3dpZGVfZGFpbHlbWzFdXSkNCiAgZmlnIDwtIGFkZF90cmFjZShmaWcsIHk9fnksIHg9fngsIGRhdGE9Y291bnRyeV9kZiwgdHlwZT0ic2NhdHRlciIsIG1vZGU9ImxpbmVzIiwgbmFtZSA9IGNvbG5hbWVzKHRvcDEwX2RmX3dpZGVfZGFpbHkpW2tdKQ0KfQ0KDQpmaWcgPC0gZmlnICU+JSBsYXlvdXQoDQogICAgdGl0bGUgPSAiRGFpbHkgQ29uZmlybWVkIENhc2VzIFNpbmNlIEZpcnN0IDI1IENhc2VzIiwNCiAgICB4YXhpcyA9IGxpc3QodGl0bGU9J0RheXMgU2luY2UgRmlyc3QgMjUgQ2FzZXMnLCByYW5nZXNsaWRlciA9IGxpc3QodHlwZSA9ICJpbnQiKSksDQogICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIkRhaWx5IENvdW50IikpDQoNCg0KZmlnDQpgYGANCg0KIyMjIENPVklEMTkgQ2FzZXMgU3ByZWFkIFRpbWVsYXBzZQ0KDQpUaGUgdGltZS1sYXBzZSB3YXMgcHJvZHVjZWQgdGhyb3VnaCBnZ2FuaW1hdGUgYW5kIHNob3dzIHRoZSBzcHJlYWQgb2YgdGhlIHZpcnVzIHNpbmNlIDIySmFuMjAyMC4gVGhlIHRpbWUtbGFwc2UgY3ljbGVzIHRocm91Z2ggdGhlIGRhdGVzLCBzaG93aW5nIHRoZSBjb2xvciBjb2RlZCBpbmNyZWFzZSBvZiBjb25maXJtZWQsIHJlY292ZXJlZCwgYW5kIGRlYXRoIGNhc2VzIGFjcm9zcyB0aGUgd29ybGQuDQoNCmBgYHtyIHRpbWVsYXBzX2Nhc2VzLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGluY2x1ZGU9RkFMU0V9DQpwIDwtIGdncGxvdCgpICsNCiAgYm9yZGVycygid29ybGQiLCBjb2xvdXIgPSAid2hpdGUiLCBmaWxsID0gImdyYXk4NSIpICsNCiAgY29vcmRfbWFwKHhsaW0gPSBjKC0xODAsIDE4MCksIHlsaW0gPSBjKC01NSwgNzApKSArDQogIHRoZW1lX21hcCgpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gZmlsdGVyKGN2LCBEYXRlPD1sYXRlc3RfZGF0ZSksIGFlcyh4ID0gTG9uZywgeSA9IExhdCwgc2l6ZSA9IGxvZzIoQ291bnQpLCBjb2xvciA9IFN0YXR1cyksIGFscGhhID0gMC4yNSkgKw0KICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDEsIDE1KSkgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiYmx1ZSIsICJyZWQiLCAiZ3JlZW4iKSkgKw0KICBsYWJzKHRpdGxlID0gIkNPVklEMTkgTG9nIENvdW50IG9mIENhc2VzIChEYXRlOiB7ZnJhbWVfdGltZX0pIiwgc2l6ZSA9ICJMb2coQ2FzZXMpIikgKw0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPTI1LCBmYWNlID0gImJvbGQiKSwNCiAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTcsIGZhY2UgPSAiYm9sZCIpDQogICkgKw0KICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gNSkpLCBzaXplID0gIm5vbmUiKSArDQogIHRyYW5zaXRpb25fdGltZShEYXRlKSArDQogIGVudGVyX2ZhZGUoKSArDQogIGV4aXRfZmFkZSgpICsNCiAgZWFzZV9hZXMoImxpbmVhciIpDQoNCmRheXMgPSBhcy5udW1lcmljKGxhdGVzdF9kYXRlIC0gYXMuRGF0ZSgiMjAyMC0wMS0yMiIpKQ0KDQphbmltX3NhdmUoImNvdmlkMTlfdGltZWxhcHNlLmdpZiIsIHAsIGhlaWdodCA9IDYwMCwgd2lkdGggPSAxMDAwLCBmcHMgPSAxMCwgbmZyYW1lcyA9IGRheXMqMiwgZW5kX3BhdXNlID0gMzApDQpgYGANCiFbXShjb3ZpZDE5X3RpbWVsYXBzZS5naWYpDQoNCiMjIyBOZXcgQ2FzZXMgb2YgdGhlIERheSAoYHIgbGF0ZXN0X2RhdGVgKQ0KDQpUaGUgJ05ldyBDYXNlcyBvZiB0aGUgRGF5JyBtYXAgZGlzcGxheXMgYWxsIGNvbmZpcm1lZCBjYXNlcyBvZiB0aGUgc3BlY2lmaWVkIGRhdGUuIFRoZSBtYXAgd2FzIHByb2R1Y2VkIHRocm91Z2ggTGVhZmxldCBhbmQgcHJvdmlkZXMgYSBkZXRhaWxlZCBhbmQgaW50ZXJhY3RpdmUgbWFwIHRoYXQgc2hvd3MgdGhlIGxvY2F0aW9uIGFuZCBudW1iZXIgb2YgY2FzZXMgb2YgdGhlIGRheS4NCg0KQWxzbywgdG8gZGlmZmVyZW50aWF0ZSBpZiB0aGUgY2FzZSBvZiB0aGUgZGF5IGlzIHRoZSBmaXJzdCBjYXNlIGluIHRoZSBzcGVjaWZpZWQgbG9jYXRpb24sIGl0IGlzIGhpZ2hsaWdodGVkIHJlZC4gQWxsIHRoZSBzcGVjaWZpZWQgcG9pbnRzIG9uIHRoZSBtYXAgYXJlIGxpc3RlZCBpbiB0aGUgdGFibGUgYmVsb3csIGluY2x1ZGluZyBjdW11bGF0aXZlIGNvdW50IG9mIGVhY2ggbG9jYXRpb24uDQoNCg0KYGBge3IgZGF5X2xlYWZseV9wbG90LCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZmlyc3RfY29sb3IgPC0gY29sb3JGYWN0b3IocGFsZXR0ZSA9IGMoInJlZCIsICJibHVlIiksIGxldmVscyA9IGMoVFJVRSwgRkFMU0UpKQ0KDQpuZXdfZGF5X2xhYmVscyA8LSBmdW5jdGlvbihkZikgew0KICBsYWJzIDwtIGxhcHBseShzZXEobnJvdyhkZikpLCBmdW5jdGlvbihpKSB7DQogICAgcGFzdGUwKA0KICAgICAgIkNvdW50cnk6ICIsIGRmW2ksICJDb3VudHJ5X1JlZ2lvbiJdLCAiPGJyPiAiLA0KICAgICAgIlByb3ZpbmNlOiAiLCBkZltpLCAiUHJvdmluY2VfU3RhdGUiXSwgIjxicj4iLA0KICAgICAgIkRheSBDb3VudDogIiwgZGZbaSwgIkRhaWx5X0NvdW50Il0sICI8YnI+IiwNCiAgICAgICJGaXJzdCBDYXNlOiAiLCBkZltpLCAiRmlyc3RfQ2FzZSJdLCAiPGJyPiIsDQogICAgICAiRGF0ZTogIiwgZGZbaSwgIkRhdGUiXQ0KICAgICkNCiAgfSkNCn0NCg0KbGVhZmxldChkYXRhID0gbmV3X2Nhc2VzX2RheSwgd2lkdGggPSAiMTAwJSIpICU+JQ0KICBhZGRUaWxlcygpICU+JQ0KICBhZGRDaXJjbGVNYXJrZXJzKA0KICAgIGxhdCA9IH5MYXQsDQogICAgbG5nID0gfkxvbmcsDQogICAgcmFkaXVzID0gfiBsb2coQ291bnQpIC8gMS4yNSwNCiAgICBsYWJlbCA9IGxhcHBseShuZXdfZGF5X2xhYmVscyhuZXdfY2FzZXNfZGF5KSwgaHRtbHRvb2xzOjpIVE1MKSwNCiAgICBjb2xvciA9IH4gZmlyc3RfY29sb3IoRmlyc3RfQ2FzZSkNCiAgKSAlPiUNCiAgYWRkTGVnZW5kKCJib3R0b21yaWdodCIsDQogICAgcGFsID0gZmlyc3RfY29sb3IsIHZhbHVlcyA9IH5GaXJzdF9DYXNlLA0KICAgIHRpdGxlID0gIkZpcnN0IENhc2UgKERheSkiLA0KICAgIG9wYWNpdHkgPSAwLjc1DQogICkNCmBgYA0KDQpgYGB7ciBkYXlfdGFibGVfbmV3LCBlY2hvPUZBTFNFfQ0KZGZfbmV3X2Nhc2VzX2RheSA8LSBuZXdfY2FzZXNfZGF5ICU+JQ0KICBzZWxlY3QoDQogICAgRGF0ZSwgQ291bnRyeV9SZWdpb24sIFByb3ZpbmNlX1N0YXRlLA0KICAgIENvdW50LCBEYWlseV9Db3VudCwgV2Vla2x5X0NvdW50LCBGaXJzdF9DYXNlDQogICkNCmRmX25ld19jYXNlc19kYXkNCmBgYA0KDQojIyMgTmV3IENhc2VzIG9mIHRoZSBXZWVrIChgciBsYXRlc3RfZGF0ZWApDQoNClRoZSAnTmV3IENhc2VzIG9mIHRoZSBXZWVrJyBtYXAgZGlzcGxheXMgYWxsIGNvbmZpcm1lZCBjYXNlcyBvZiB0aGUgd2VlayBzdGFydGluZyBmcm9tIHRoZSBzcGVjaWZpZWQgZGF0ZS4gVGhpcyBtYXAgc2hvd3MgdGhlIHNhbWUgaW5mb3JtYXRpb24gYXMgdGhlIGRhaWx5IGNhc2VzIG1hcCBidXQgaW5jbHVkZXMgYWxsIGNhc2VzIGluIHRoZSBwYXN0IHdlZWsuDQoNCmBgYHtyIHdlZWtfbGVhZmx5X3Bsb3QsIGVjaG89RkFMU0V9DQpmaXJzdF9jb2xvciA8LSBjb2xvckZhY3RvcihwYWxldHRlID0gYygicmVkIiwgImJsdWUiKSwgbGV2ZWxzID0gYyhUUlVFLCBGQUxTRSkpDQoNCm5ld193ZWVrX2xhYmVscyA8LSBmdW5jdGlvbihkZikgew0KICBsYWJzIDwtIGxhcHBseShzZXEobnJvdyhkZikpLCBmdW5jdGlvbihpKSB7DQogICAgcGFzdGUwKA0KICAgICAgIkNvdW50cnk6ICIsIGRmW2ksICJDb3VudHJ5X1JlZ2lvbiJdLCAiPGJyPiAiLA0KICAgICAgIlByb3ZpbmNlOiAiLCBkZltpLCAiUHJvdmluY2VfU3RhdGUiXSwgIjxicj4iLA0KICAgICAgIldlZWsgQ291bnQ6ICIsIGRmW2ksICJXZWVrbHlfQ291bnQiXSwgIjxicj4iLA0KICAgICAgIkZpcnN0IENhc2U6ICIsIGRmW2ksICJGaXJzdF9DYXNlIl0sICI8YnI+IiwNCiAgICAgICJEYXRlOiAiLCBkZltpLCAiRGF0ZSJdDQogICAgKQ0KICB9KQ0KfQ0KDQpsZWFmbGV0KGRhdGEgPSBuZXdfY2FzZXNfd2Vlaywgd2lkdGggPSAiMTAwJSIpICU+JQ0KICBhZGRUaWxlcygpICU+JQ0KICBhZGRDaXJjbGVNYXJrZXJzKA0KICAgIGxhdCA9IH5MYXQsDQogICAgbG5nID0gfkxvbmcsDQogICAgcmFkaXVzID0gfiBsb2coQ291bnQpIC8gMS4yNSwNCiAgICBsYWJlbCA9IGxhcHBseShuZXdfd2Vla19sYWJlbHMobmV3X2Nhc2VzX3dlZWspLCBodG1sdG9vbHM6OkhUTUwpLA0KICAgIGNvbG9yID0gfiBmaXJzdF9jb2xvcihGaXJzdF9DYXNlKQ0KICApICU+JQ0KICBhZGRMZWdlbmQoImJvdHRvbXJpZ2h0IiwNCiAgICBwYWwgPSBmaXJzdF9jb2xvciwgdmFsdWVzID0gfkZpcnN0X0Nhc2UsDQogICAgdGl0bGUgPSAiRmlyc3QgQ2FzZSAoV2VlaykiLA0KICAgIG9wYWNpdHkgPSAwLjc1DQogICkNCmBgYA0KDQpgYGB7ciB3ZWVrX3RhYmxlX25ldywgZWNobz1GQUxTRX0NCmRmX25ld19jYXNlc193ZWVrIDwtIG5ld19jYXNlc193ZWVrICU+JQ0KICBzZWxlY3QoDQogICAgRGF0ZSwgQ291bnRyeV9SZWdpb24sIFByb3ZpbmNlX1N0YXRlLA0KICAgIENvdW50LCBEYWlseV9Db3VudCwgV2Vla2x5X0NvdW50LCBGaXJzdF9DYXNlDQogICkNCmRmX25ld19jYXNlc193ZWVrDQpgYGANCg0KYGBge3IgY2FzZXNfY291bnRfcGVyY2VudF9hZ2csIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVycm9yPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KcGVyY2VudF9jb3VudCA8LSBjdl9tZXJnZSAlPiUNCiAgZ3JvdXBfYnkoRGF0ZSkgJT4lDQogIGZpbHRlcihEYXRlIDw9IGxhdGVzdF9kYXRlKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIENvbmZpcm1lZCA9IHN1bShDb25maXJtZWQsIG5hLnJtID0gVFJVRSksDQogICAgRGVhZCA9IHN1bShEZWFkLCBuYS5ybSA9IFRSVUUpLA0KICAgIFJlY292ZXJlZCA9IHN1bShSZWNvdmVyZWQsIG5hLnJtID0gVFJVRSkNCiAgKQ0KZm9yICh4IGluIHNlcSgxLCBucm93KHBlcmNlbnRfY291bnQpKSkgew0KICBpZiAoeCA9PSAxKSB7DQogICAgcGVyY2VudF9jb3VudCREYWlseV9Db25maXJtZWRbeF0gPC0gcGVyY2VudF9jb3VudCRDb25maXJtZWRbeF0NCiAgICBwZXJjZW50X2NvdW50JERhaWx5X0RlYWRbeF0gPC0gcGVyY2VudF9jb3VudCREZWFkW3hdDQogICAgcGVyY2VudF9jb3VudCREYWlseV9SZWNvdmVyZWRbeF0gPC0gcGVyY2VudF9jb3VudCRSZWNvdmVyZWRbeF0NCiAgfQ0KICBlbHNlIHsNCiAgICBwZXJjZW50X2NvdW50JERhaWx5X0NvbmZpcm1lZFt4XSA8LSBwZXJjZW50X2NvdW50JENvbmZpcm1lZFt4XSAtIHBlcmNlbnRfY291bnQkQ29uZmlybWVkW3ggLSAxXQ0KICAgIHBlcmNlbnRfY291bnQkRGFpbHlfRGVhZFt4XSA8LSBwZXJjZW50X2NvdW50JERlYWRbeF0gLSBwZXJjZW50X2NvdW50JERlYWRbeCAtIDFdDQogICAgcGVyY2VudF9jb3VudCREYWlseV9SZWNvdmVyZWRbeF0gPC0gcGVyY2VudF9jb3VudCRSZWNvdmVyZWRbeF0gLSBwZXJjZW50X2NvdW50JFJlY292ZXJlZFt4IC0gMV0NCiAgfQ0KfQ0KDQpkZWFkX2NvbmZfcmVjdiA8LSBwZXJjZW50X2NvdW50ICU+JQ0KICBzZWxlY3QoRGF0ZSwgQ29uZmlybWVkLCBEZWFkLCBSZWNvdmVyZWQpICU+JQ0KICBnYXRoZXIoa2V5PSJTdGF0dXMiLCB2YWx1ZT0iQ291bnQiLCAtRGF0ZSkNCg0KZGVhZF9jb25mX3JlY3ZfZGFpbHkgPC0gcGVyY2VudF9jb3VudCAlPiUNCiAgc2VsZWN0KERhdGUsIERhaWx5X0NvbmZpcm1lZCwgRGFpbHlfRGVhZCwgRGFpbHlfUmVjb3ZlcmVkKSAlPiUNCiAgZ2F0aGVyKGtleT0iRGFpbHkiLCB2YWx1ZT0iQ291bnQiLCAtRGF0ZSkNCg0KcGVyY2VudF9jb3VudCRQZXJjZW50X0RlYWQgPC0gcGVyY2VudF9jb3VudCREZWFkIC8gcGVyY2VudF9jb3VudCRDb25maXJtZWQNCg0KcGVyY2VudF9jb3VudCRQZXJjZW50X1JlY292ZXJlZCA8LSBwZXJjZW50X2NvdW50JFJlY292ZXJlZCAvIHBlcmNlbnRfY291bnQkQ29uZmlybWVkDQoNCnBlcmNlbnRfb3JnIDwtIHBlcmNlbnRfY291bnQgJT4lDQogIHNlbGVjdChEYXRlLCBQZXJjZW50X1JlY292ZXJlZCwgUGVyY2VudF9EZWFkKSAlPiUNCiAgZ2F0aGVyKGtleT0iU3RhdHVzIiwgdmFsdWU9IlBlcmNlbnQiLCAtRGF0ZSkgDQpgYGANCg0KIyMjIEdlbmVyYWwgVHJlbmRzDQoNClRoZSBwbG90cyBiZWxvdyBvdXRsaW5lcyBnZW5lcmFsIHRyZW5kcyBzZWVuIG9mIHRoZSB2aXJ1cyBvdmVyIHRpbWU6DQoNCigxKQnigJxQZXJjZW50IG9mIENhc2VzIFJlY292ZXJlZCBvciBEZWFkIHBlciBEYXnigJ06IHRoZSB0b3RhbCBwZXJjZW50IG9mIGNhc2VzIHRoYXQgaGF2ZSByZXN1bHRlZCBpbiByZWNvdmVyeSBvciBkZWF0aCBwZXIgY29uZmlybWVkIGNhc2UNCg0KKDIpCSJDdW11bGF0aXZlIFN0YXR1cyBvZiBBbGwgQ2FzZXMiOiB0aGUgY29udGludW91cyBpbmNyZWFzZSBvZiBjb25maXJtZWQsIGRlYXRoLCBhbmQgcmVjb3ZlcmVkIGNhc2VzIG92ZXIgdGltZSANCg0KKDMpCeKAnFN0YXR1cyBvZiBDYXNlcyBwZXIgRGF54oCdOiB0aGUgbnVtYmVyIG9mIGNhc2VzIGNsYXNzaWZpZWQgYXMgY29uZmlybWVkLCBkZWF0aCwgb3IgcmVjb3ZlcmVkIHN1YnRyYWN0ZWQgdG8gc2hvdyBwZXIgZGF5IGNoYW5nZXMNCg0KYGBge3IgcGxvdF9wZXJjZW50X2Nhc2VzLCBlY2hvPUZBTFNFLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00LjV9DQpnZ3Bsb3QocGVyY2VudF9vcmcsIGFlcyh4ID0gRGF0ZSwgeT1QZXJjZW50LCBncm91cD1TdGF0dXMpKSArDQogIGdlb21fbGluZShhZXMoY29sb3IgPSBTdGF0dXMpLCBzaXplPTEuMykgKw0KICBnZ3RpdGxlKCJQZXJjZW50IG9mIENhc2VzIFJlY292ZXJlZCBvciBEZWFkIHBlciBEYXkiKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJyZWQzIiwgImdyZWVuMyIpKSArDQogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICI3IGRheSIsIA0KICAgICAgICAgICAgICAgZGF0ZV9taW5vcl9icmVha3MgPSAiNyBkYXkiLCANCiAgICAgICAgICAgICAgIGRhdGVfbGFiZWxzID0gIiViICVkIikgKw0KICB0aGVtZV9saWdodCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpDQpgYGANCg0KYGBge3IgcGxvdF9jdW11bGF0aXZlX3N0YXR1cywgZWNobz1GQUxTRSwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NC41fQ0KZ2dwbG90KGRlYWRfY29uZl9yZWN2LCBhZXMoeCA9IERhdGUsIHk9Q291bnQsIGdyb3VwPVN0YXR1cykpICsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvciA9IFN0YXR1cyksIHNpemU9MS4zKSArDQogIGdndGl0bGUoIkN1bXVsYXRpdmUgU3RhdHVzIG9mIEFsbCBDYXNlcyIpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImJsdWUzIiwgInJlZDMiLCAiZ3JlZW4zIikpICsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjcgZGF5IiwgDQogICAgICAgICAgICAgICBkYXRlX21pbm9yX2JyZWFrcyA9ICI3IGRheSIsIA0KICAgICAgICAgICAgICAgZGF0ZV9sYWJlbHMgPSAiJWIgJWQiKSArDQogIHRoZW1lX2xpZ2h0KCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkNCmBgYA0KDQoNCmBgYHtyIHBsb3Rfc3RhdHVzX3Blcl9kYXksIGVjaG89RkFMU0UsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTQuNX0gIA0KZ2dwbG90KGRlYWRfY29uZl9yZWN2X2RhaWx5LCBhZXMoeCA9IERhdGUsIHk9Q291bnQsIGdyb3VwPURhaWx5KSkgKw0KICBnZW9tX2xpbmUoYWVzKGNvbG9yID0gRGFpbHkpLCBzaXplPTEuMykgKw0KICBnZ3RpdGxlKCJTdGF0dXMgb2YgQ2FzZXMgcGVyIERheSIpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImJsdWUzIiwgInJlZDMiLCAiZ3JlZW4zIikpICsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjcgZGF5IiwgDQogICAgICAgICAgICAgICBkYXRlX21pbm9yX2JyZWFrcyA9ICI3IGRheSIsIA0KICAgICAgICAgICAgICAgZGF0ZV9sYWJlbHMgPSAiJWIgJWQiKSsNCiAgdGhlbWVfbGlnaHQoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCg0KDQoNCg0KYGBge3IgZ2l0aHViX3B1c2hpbmdfY29tbWFuZHMsIGluY2x1ZGU9RkFMU0V9DQpnaXRzdGF0dXMgPC0gZnVuY3Rpb24oZGlyID0gZ2V0d2QoKSkgew0KICBjbWRfbGlzdCA8LSBsaXN0KA0KICAgIGNtZDEgPSB0b2xvd2VyKHN1YnN0cihkaXIsIDEsIDIpKSwNCiAgICBjbWQyID0gcGFzdGUoImNkIiwgZGlyKSwNCiAgICBjbWQzID0gImdpdCBzdGF0dXMiDQogICkNCiAgY21kIDwtIHBhc3RlKHVubGlzdChjbWRfbGlzdCksIGNvbGxhcHNlID0gIiAmICIpDQogIHNoZWxsKGNtZCkNCn0NCg0KZ2l0YWRkIDwtIGZ1bmN0aW9uKGRpciA9IGdldHdkKCkpIHsNCiAgY21kX2xpc3QgPC0gbGlzdCgNCiAgICBjbWQxID0gdG9sb3dlcihzdWJzdHIoZGlyLCAxLCAyKSksDQogICAgY21kMiA9IHBhc3RlKCJjZCIsIGRpciksDQogICAgY21kMyA9ICJnaXQgYWRkIC0tYWxsIg0KICApDQogIGNtZCA8LSBwYXN0ZSh1bmxpc3QoY21kX2xpc3QpLCBjb2xsYXBzZSA9ICIgJiAiKQ0KICBzaGVsbChjbWQpDQp9DQoNCmdpdGNvbW1pdCA8LSBmdW5jdGlvbihtc2cgPSBwYXN0ZSgiY2hvcmU6IGF1dG8tdXBkYXRlIiwgU3lzLnRpbWUoKSwgImVzdCIpLCBkaXIgPSBnZXR3ZCgpKSB7DQogIGNtZCA8LSBzcHJpbnRmKCJnaXQgY29tbWl0IC1tXCIlc1wiIiwgbXNnKQ0KICBzeXN0ZW0oY21kKQ0KfQ0KDQpnaXRwdXNoIDwtIGZ1bmN0aW9uKGRpciA9IGdldHdkKCkpIHsNCiAgY21kX2xpc3QgPC0gbGlzdCgNCiAgICBjbWQxID0gdG9sb3dlcihzdWJzdHIoZGlyLCAxLCAyKSksDQogICAgY21kMiA9IHBhc3RlKCJjZCIsIGRpciksDQogICAgY21kMyA9ICJnaXQgcHVzaCINCiAgKQ0KICBjbWQgPC0gcGFzdGUodW5saXN0KGNtZF9saXN0KSwgY29sbGFwc2UgPSAiICYgIikNCiAgc2hlbGwoY21kKQ0KfQ0KDQpnaXQycjo6Y29uZmlnKHVzZXIubmFtZSA9ICJhbGJlY2hlbiIsIHVzZXIuZW1haWwgPSAiYWxjaGVuMjQ0QGdtYWlsLmNvbSIpDQpgYGANCg0KYGBge3Igc2F2ZV9kb2MsIGluY2x1ZGU9RkFMU0V9DQpkb2N1bWVudFNhdmUoZ2V0QWN0aXZlRG9jdW1lbnRDb250ZXh0KCkpDQpTeXMuc2xlZXAoMjApDQpgYGANCg0KYGBge3IgZ2l0aHViX3B1c2hfYWxsLCBpbmNsdWRlPUZBTFNFfQ0KZ2l0c3RhdHVzKCkNCmdpdGFkZCgpDQpnaXRjb21taXQoKQ0KZ2l0cHVzaCgpDQpgYGANCg==